package com.tenqian.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HttpClient4.3工具类
 */
public class HttpClientUtils {
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录

    private static RequestConfig requestConfig = null;

    static {
        // 设置请求和传输超时时间
        requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).build();
    }

    /**
     * post 请求
     *
     * @param url
     * @param params
     * @param headers
     * @return
     */
    public static JSONObject httpPost(String url, Map<String, String> params, Map<String, String> headers) {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        // 设置请求和传输超时时间
        post.setConfig(requestConfig);
        if (headers != null && !headers.isEmpty()) {
            for (String s : headers.keySet()) {
                post.addHeader(s, headers.get(s));
            }
        }
        List<NameValuePair> data = new ArrayList<NameValuePair>();
        if (params != null && !params.isEmpty()) {
            for (String s : params.keySet()) {
                data.add(new BasicNameValuePair(s, params.get(s)));
            }
        }
        if (data.size() > 0) {
            UrlEncodedFormEntity formEntity = null;
            try {
                formEntity = new UrlEncodedFormEntity(data);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            post.setEntity(formEntity);
        }

        JSONObject jsonResult = getJsonObject(url, "", httpClient, post);
        return jsonResult;
    }


    /**
     * post请求传输json参数
     *
     * @param url       url地址
     * @param jsonParam 参数
     * @return
     */
    public static JSONObject httpPost(String url, JSONObject jsonParam) {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        // 设置请求和传输超时时间
        httpPost.setConfig(requestConfig);
        JSONObject jsonResult = getJsonObject(url, jsonParam, httpClient, httpPost);
        return jsonResult;
    }

    /**
     * post请求传输json参数
     *
     * @param url       url地址
     * @param jsonParam 参数
     * @param headers   头信息
     * @return
     */
    public static JSONObject httpPost(String url, JSONObject jsonParam, Map<String, String> headers) {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        // 设置请求和传输超时时间
        httpPost.setConfig(requestConfig);
        for (String s : headers.keySet()) {
            httpPost.addHeader(s, headers.get(s));
        }
        JSONObject jsonResult = getJsonObject(url, jsonParam, httpClient, httpPost);
        return jsonResult;
    }

    /**
     * post请求传输String参数 例如：name=Jack&sex=1&type=2
     * Content-type:application/x-www-form-urlencoded
     *
     * @param url      url地址
     * @param strParam 参数
     * @return
     */
    public static JSONObject httpPost(String url, String strParam) {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        jsonResult = getJsonObject(url, strParam, httpClient, httpPost);
        return jsonResult;
    }

    private static JSONObject getJsonObject(String url, String strParam, CloseableHttpClient httpClient, HttpPost httpPost) {
        JSONObject jsonResult = null;
        try {
            if (StringUtils.isNotBlank(strParam)) {
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(strParam, "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/x-www-form-urlencoded");
                httpPost.setEntity(entity);
            }
            CloseableHttpResponse result = httpClient.execute(httpPost);
            // 请求发送成功，并得到响应
            // 请求发送成功，并得到响应
            jsonResult = parseResult(url, result);
        } catch (IOException e) {
            logger.error("post请求提交失败:" + url, e);
        } finally {
            httpPost.releaseConnection();
        }
        return jsonResult;
    }

    /**
     * post请求传输String参数 例如：name=Jack&sex=1&type=2
     * Content-type:application/x-www-form-urlencoded
     *
     * @param url      url地址
     * @param strParam 参数
     * @return
     */
    public static JSONObject httpPost(String url, String strParam, Map<String, String> headers) {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        for (String s : headers.keySet()) {
            httpPost.addHeader(s, headers.get(s));
        }
        jsonResult = getJsonObject(url, strParam, httpClient, httpPost);
        return jsonResult;
    }

    /**
     * 发送get请求
     *
     * @param url 路径
     * @return
     */
    public static JSONObject httpGet(String url) {
        // get请求返回结果
        CloseableHttpClient client = HttpClients.createDefault();
        // 发送get请求
        HttpGet request = new HttpGet(url);
        JSONObject jsonResult = getJsonObject(url, client, request);
        return jsonResult;
    }

    /**
     * 发送get请求
     *
     * @param url 路径
     * @return
     */
    public static String httpGetReturnStr(String url) {
        // get请求返回结果
        CloseableHttpClient client = HttpClients.createDefault();
        // 发送get请求
        HttpGet request = new HttpGet(url);
        try {
            CloseableHttpResponse result = client.execute(request);
            String str = EntityUtils.toString(result.getEntity(), "utf-8");
            return str;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param url
     * @param params
     * @param headers
     * @return
     */
    public static JSONObject httpGet(String url, Map<String, String> params, Map<String, String> headers) {
        StringBuilder stringBuilder = new StringBuilder(url);
        //添加参数
        if (!params.isEmpty()) {
            stringBuilder.append("?");
            for (String s : params.keySet()) {
                stringBuilder.append(s).append("=").append(params.get(s)).append("&");
            }
            stringBuilder.substring(0, stringBuilder.length() - 1);
        }
        //如果头不为空
        if (null != headers && !headers.isEmpty()) {
            return httpGet(stringBuilder.toString(), headers);
        }
        return httpGet(stringBuilder.toString());
    }

    /**
     * 发送get请求
     *
     * @param url     请求路径
     * @param headers 请求头
     * @return
     */
    public static JSONObject httpGet(String url, Map<String, String> headers) {
        // get请求返回结果
        CloseableHttpClient client = HttpClients.createDefault();
        // 发送get请求
        HttpGet request = new HttpGet(url);
        for (String s : headers.keySet()) {
            request.addHeader(s, headers.get(s));
        }
        JSONObject jsonResult = getJsonObject(url, client, request);
        return jsonResult;
    }

    //自动抽取的方法request
    private static JSONObject getJsonObject(String url, CloseableHttpClient client, HttpGet request) {
        JSONObject jsonResult = null;
        request.setConfig(requestConfig);
        try {
            CloseableHttpResponse result = client.execute(request);
            // 请求发送成功，并得到响应
            jsonResult = parseResult(url, result);
        } catch (IOException e) {
            logger.error("get请求提交失败:" + url, e);
        } finally {
            request.releaseConnection();
        }
        return jsonResult;
    }

    //将结果封装成JSONObject
    private static JSONObject parseResult(String url, CloseableHttpResponse result) {
        JSONObject jsonResult = null;
        if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String str = "";
            try {
                // 读取服务器返回过来的json字符串数据
                str = EntityUtils.toString(result.getEntity(), "utf-8");
                // 把json字符串转换成json对象
                jsonResult = JSONObject.parseObject(str);
            } catch (Exception e) {
                logger.error("请求提交失败:" + url, e);
            }
        } else logger.error("请求失败:" + result.toString());
        return jsonResult;
    }

    //自动抽取的方法httpPost
    private static JSONObject getJsonObject(String url, JSONObject jsonParam, CloseableHttpClient httpClient, HttpPost httpPost) {
        JSONObject jsonResult = null;
        try {
            if (null != jsonParam) {
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(jsonParam.toJSONString(), "utf-8");
                logger.info("参数:{}", jsonParam.toJSONString());
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }
            CloseableHttpResponse result = httpClient.execute(httpPost);

            // 请求发送成功，并得到响应
            jsonResult = parseResult(url, result);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("post请求提交失败:" + url, e);
        } finally {
            httpPost.releaseConnection();
        }
        return jsonResult;
    }

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("telephone", "15906812686");
        JSONObject jsonObject = httpPost("http://localhost:8080/tqcrm/user/sendCode", map, null);
        System.out.println(jsonObject);
    }
}